/**
 * @author Praveen Krupakaran (A0092625)
 */

package sg.edu.nus.iss.team4ft.ui;

import java.awt.BorderLayout;
import java.awt.Choice;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Calendar;
import java.util.Date;

import sg.edu.nus.iss.team4ft.exception.InvalidOperationException;
import sg.edu.nus.iss.team4ft.util.AppConstant;
import sg.edu.nus.iss.team4ft.util.DateUtil;

public class DateControl extends Panel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Label dateLabel = new Label();
	private Choice day = new Choice();
	private Choice month = new Choice();
	private Choice year = new Choice();
	private Label errorText = new Label();
	private Mode mode = Mode.View;
	private Date date;
	private boolean isControlEnabled = true;
	//private String[] months = {"January","February","March","April","May","June","July","August","September","October","November","December"};
	
	public DateControl(String labelText, Mode mode){
		this.setPreferredSize(new java.awt.Dimension(350, 25));
		setMode(mode);
		loadControlValues(labelText);
	}
	
	public void setText(String text){
		dateLabel.setText(text);
	}
//	
//	public DateControl(String labelText, Mode mode, Date date){
//		this.setPreferredSize(new java.awt.Dimension(300, 25));
//		setMode(mode);
//		loadControlValues(labelText);
//		setDate(date);
//	}
	
	public void setMode(Mode mode) {
		this.mode = mode;
		boolean isEnabled = true;
		
		if(this.mode == Mode.View)
			isEnabled = false;
		
		day.setEnabled(isEnabled);
		month.setEnabled(isEnabled);
		year.setEnabled(isEnabled);
	}
	
	/**
	 * 
	 * @param labelText
	 */
	private void loadControlValues(String labelText) {
		this.setLayout(new BorderLayout());
		this.dateLabel.setPreferredSize(new java.awt.Dimension(80, 25));
		dateLabel.setText(labelText);
		errorText.setForeground(Color.RED);
		errorText.setText(AppConstant.ERROR_INVALID_DATE);
		errorText.setVisible(false);
		
		day.addItem(AppConstant.DD);
		for(Integer i = 1; i < 32; i++){
			day.addItem(i.toString());
		}
		
		month.addItem(AppConstant.MM);
		for(Integer i = 1; i < 13; i++){
			month.addItem(i.toString());
		}
		
		year.addItem(AppConstant.YYYY);
		for(Integer i = 2009; i < 2020; i++){
			year.addItem(i.toString());
		}
		
		ItemListener dateChange = new ItemListener(){
			public void itemStateChanged(ItemEvent e){
				setDate();
			}
		};
		day.addItemListener(dateChange);		
		year.addItemListener(dateChange);
		month.addItemListener(dateChange);

		this.add("West",dateLabel);
		Panel p = new Panel(new FlowLayout(FlowLayout.LEFT));
		p.setPreferredSize(new java.awt.Dimension(200, 25));
		p.add(day);
		p.add(month);
		p.add(year);
		this.add("Center",p);
		this.add("East",errorText);
	}
	
	public Date getDate() throws InvalidOperationException{
		if(!isControlEnabled)
			return null;
		if(date == null)
			throw new InvalidOperationException(AppConstant.ERROR_INVALID_DATE);
		return date;
	}
	
	private void setDate(Date date){
		this.date = date;
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.get(Calendar.YEAR);
		day.select((new Integer(cal.get(Calendar.DAY_OF_MONTH))).toString());
		month.select((new Integer(cal.get(Calendar.MONTH) + 1)).toString());
		year.select((new Integer(cal.get(Calendar.YEAR))).toString());
		//isValidDate();		
	}
	
	@Override
	public void setEnabled(boolean arg0) {
		isControlEnabled = arg0;
		if(arg0)
			setDate(DateUtil.getDate());
		else
			setDefaultDate();
		this.day.setEnabled(arg0);
		this.month.setEnabled(arg0);
		this.year.setEnabled(arg0);
		this.dateLabel.setEnabled(arg0);		
	}
	
	private void setDate(){
		if(isValidDate()){
			int yr = new Integer(this.year.getSelectedItem());
			int mon = new Integer(this.month.getSelectedItem()) - 1;
			int day = new Integer(this.day.getSelectedItem());	

			this.date = getDate(yr, mon, day);
		}		
	}
	
	private void setDefaultDate(){
		this.date = null;
		day.select(AppConstant.DD);
		month.select(AppConstant.MM);
		year.select(AppConstant.YYYY);	
	}

	private Date getDate(int yr, int mon, int day) {
		Calendar cal = Calendar.getInstance();
		cal.set(yr, mon, day);
		return cal.getTime();
	}
		
	private boolean isValidDate() {
		boolean isValid = false;
		errorText.setVisible(false);
		try
		{
			int yr = new Integer(this.year.getSelectedItem());
			int mon = new Integer(this.month.getSelectedItem()) - 1;
			int day = new Integer(this.day.getSelectedItem());
						
			this.date = getDate(yr, mon, day);
			isValid = true;			
		}
		catch (Exception e) {
			this.date = null;
			errorText.setVisible(true);
		}
		errorNotification();		
		return isValid;
	}

	private void errorNotification() {
		this.repaint();
	}
}

enum Month {
	JAN(1),
	FEB(2),
	MAR(3),
	APR(4),
	MAY(5),
	JUN(6),
	JUL(7),
	AUG(8),
	SEP(9),
	OCT(10),
	NOV(11),
	DEC(12);
	private int code;
	private Month(int c){
		this.code = c;
	}
	
	public int getCode(){
		return code;
	}
}
